<?php

/**
 * 尚品-圣卡斯 SDK
 * @author chenyun
 * 
 */

namespace App\Service\VendorClient\Shopshengkasi;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use App\Model\PssModel\ServiceConfig;

class ShopshengkasiApiClient
{
    private $account  = 'shopshengkasi';
    protected $config;
 
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        
        ini_set('serialize_precision', 16);
        
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        
        //运费
        $deliver_money  = $this->MultiplyByOneHundred($orderInfo['deliver_money']);
        //商品下单组
        $goods = [];
        $productAmt    = $TaxAmt = 0 ;
        foreach ($params['orderGoods'] as $key => $item )
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //如果商品除不尽，得多取以为，减去实际金额为折扣，折扣不能为负数
            if( $key == 0 ) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money,(string)$quantity,3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney,(string)100,1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100,2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney,2);
            }
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv((string)$singleGoodsPrice,'100',2);
            $totalGoods         = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);

            //含税税率
            $tax_rate           = bcadd('1', (string)$item['tax_rate'],4);
            
            //不含税价格
            $not_tax_price      = bcdiv((string)$singleGoodsPrice, (string)$tax_rate,3);
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = ceil(bcmul((string)$not_tax_price,(string)'100',1));
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = bcdiv((string)$not_tax_price,'100',2);
            
            //税金
            $singleGoodsTax     = bcsub((string)$singleGoodsPrice, (string)$not_tax_price,3);
            
            //单个商品总税金
            $totalGoodsTax  = bcmul((string)$singleGoodsTax,(string)$buyAcount,2);
            $totalGoodsTax  = $this->MultiplyByOneHundred($totalGoodsTax);
            //单个商品总不含税价格
            $totalGoods     = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);
            $totalGoods     = $this->MultiplyByOneHundred($totalGoods);
            $goods[]= [
                'goods_no'         => $item['supplier_skucode'],
                'number'           => $buyAcount,
                'total'            => $totalGoods,
            ];
            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
            $TaxAmt = bcadd((string)$TaxAmt,(string)$totalGoodsTax);
        }
        //实际下单金额
        $real_total_money = $this->MultiplyByOneHundred($orderInfo['real_total_money']);
        //优惠金额
        $discount_money = bcsub((string)$productAmt,$real_total_money);
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        
        //支付时间
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        $pay_time       = date('Y-m-d H:i:s',$pay_time);
        
        //支付流水号
        $pay_sn         = $order['paySerial']??$orderInfo['pay_sn'];

        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;

        //获取上游供应商支付方式路由
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        
        //创建订单数据
        $order = [
            "order_no"         => $orderInfo["supplier_dsn"],
            "f_shop_id"        => "",
            "pdd_shop_id"      => "",
            "create_time"      => date("Y-m-d H:i:s",time()),
            "pay_time"         => $pay_time,
            "total_price"      => $real_total_money,
            "total_tax"        => $TaxAmt,
            "total_fright"     => $deliver_money,
            "f_discount"       => $discount_money,
            "customs"          => [
                'idcard'            => $orderInfo["buyer_idcard"],
                'idcard_name'       => $orderInfo["buyer_realname"],
                'plaform_code'      => $enterpriseNum,
                'pay_id'            => $PayCompanyCode,
                'pay_no'            => $pay_sn,
                'order_decla_no'    => $orderInfo["supplier_dsn"],
            ],
            "address"          => [
                'consignee'         => $orderInfo["receive_name"],
                'consignee_phone'   => $orderInfo["recveive_phone"],
                'province'          => $orderInfo['province'],
                'city'              => $orderInfo['city'],
                'area'              => $orderInfo['district'],
                'address'           => $orderInfo['receive_address'],
            ],
            "goods"            => $goods,
        ];

        $data = [
            "warehouse_no"       => $this->config["warehouse_no"],
            "charset"            => "UTF-8",
            "customer_no"        => $this->config["customer_no"],
            "nonce_str"          => $this->randstrpay(),
            "method"             => "order_add",
            "sign_type"          => "MD5",
            "query_params"       => json_encode($order,JSON_UNESCAPED_UNICODE),
        ];
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => $data,
        ];
        return $this->execute($requestParam);
    }
    /**
     * 取消订单
     */
    public function cancelOrder($params = []) {

        $order=[
            "order_no"       => $params['supplierOrder']['supplier_dsn'],
        ];
        $data = [
            "warehouse_no"       => $this->config["warehouse_no"],
            "charset"            => "UTF-8",
            "customer_no"        => $this->config["customer_no"],
            "nonce_str"          => $this->randstrpay(),
            "method"             => "order_cancel",
            "sign_type"          => "MD5",
            "query_params"       => json_encode($order,JSON_UNESCAPED_UNICODE),
        ];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      => $data
        ];
        return $this->execute($requestParam);
    }
    /**
     * 查询商品信息
     */
    public function queryGoodsList($param = [])
    {
        $query_params = implode(",",$param["skuNos"]);
        $data = [
            "warehouse_no"       => $this->config["warehouse_no"],
            "charset"            => "UTF-8",
            "customer_no"        => $this->config["customer_no"],
            "nonce_str"          => $this->randstrpay(),
            "method"             => "inventory",
            "sign_type"          => "MD5",
            "query_params"       => $query_params,
        ];
        $requestParam = [
            'method'    => 'queryGoodsList',
            'data'      => $data
        ];
        $result =  $this->execute($requestParam);
        if($result["code"] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL,$result['msg'],[
                'has_next'  => true,
                'total'     => 0,
                'list'      => []
            ]);
        }
        if(isset($result["data"]["data"]) && empty($result["data"]["data"])){
            return Normal::returnCode(Normal::FAIL,"当前页没有查到库存！",[
                'has_next'  => true,
                'total'     => 0,
                'list'      => []
            ]);
        }
        $details = [];
        foreach ($result["data"]["data"] as $data){
            $details[] = [
                'goodsNo'   => $data["goodsNo"],
                'remain'    => $data["remain"],
            ];
        }
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'has_next'  => true,
            'total'     => count($details),
            'list'      => $details
        ]);
    }
    /**
     * 随机32位字符串
     */
    function randstrpay($length=32) {
        $rand='';
        $randstr= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $max = strlen($randstr)-1;
        mt_srand((double)microtime()*1000000);
        for($i=0;$i<$length;$i++) {
            $rand.=$randstr[mt_rand(0,$max)];
        }
        return $rand;
    }
    /**
     * 转换为分
     * @return string
     */
    private function MultiplyByOneHundred($money)
    {
        return bcmul($money,100);
    }
    /**
     * 加签
     * @param array $param
     */
    protected function getSign ($param)
    {
        //第一步：排序
        ksort($param);
        $str = "";
        //第二步：拼接字符串，格式：appId=1688bizData=W3siY2l0eSI6IuadreW3njEiLCJjb3VudCI6M31dserviceName=order.cancelv=4.0
        foreach($param as $k =>$v){
            $str.= $k."=".$v."&";
        }
        $str = substr($str,0,-1);
        $str = $str.$this->config["secret"];
        return strtoupper(md5($str));
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {
        if(empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method = $param["method"];
        $url    = $this->config["baseurl"];
        $param["data"]["sign"]   = $this->getSign($param["data"]);
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => '',
                'header'    =>[
                    "Content-Type: application/x-www-form-urlencoded"
                    ],
            ],
        ];

        if( in_array($method,['queryGoodsList']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = @json_decode($res,true);
        if(isset($resHttp['errorCode']) && $resHttp['errorCode'] == 0 ) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        $message = isset($resHttp['errorMsg']) ? $resHttp['errorMsg'] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
}